﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Generic
{
    class Program
    {
        static void Main(string[] args)
        {
            //泛型在类上的实现
            MyGenericArray<int> intArray = new MyGenericArray<int>(5);
            for (int c = 0; c < 5; c++)
            {
                intArray.SetItem(c, c * 5);
            }
            for (int c = 0; c < 5; c++)
            {
                Console.Write(intArray.GetItem(c) + " ");
            }

            Console.WriteLine();

            intArray.GenericMethod<string>("Hello Generic!");
            intArray.GenericMethod<int>(100);

            MyGenericArray<char> charArray = new MyGenericArray<char>(5);
            for (int c = 0; c < 5; c++)
            {
                charArray.SetItem(c, (char)(c + 97));
            }
            for (int c = 0; c < 5; c++)
            {
                Console.Write(charArray.GetItem(c) + " ");
            }
            Console.WriteLine();


            //泛型在方法上的实现
            int a, b;
            char m, n;
            a = 10;
            b = 20;
            m = 'I';
            n = 'V';
            Swap<int>(ref a, ref b);
            Swap<char>(ref m, ref n);

            //泛型在委托上的实现
            NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
            NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
            nc1(25);
            Console.WriteLine(num);
            nc2(5);
            Console.WriteLine(num);

            Console.ReadLine();
        }


        private static void Swap<T>(ref T lhs, ref T rhs)
        {
            T temp;
            temp = lhs;
            lhs = rhs;
            rhs = temp;
        }

        static int num = 10;
        public static int AddNum(int p)
        {
            num += p;
            return num;
        }
        public static int MultNum(int p)
        {
            num *= p;
            return num;
        }
    }


    public class MyGenericArray<T> where T : struct  //限制T为值类型
    {
        private T[] array;
        public MyGenericArray(int size)
        {
            array = new T[size + 1];
        }

        public T GetItem(int index)
        {
            return array[index];
        }

        public void SetItem(int index, T value)
        {
            array[index] = value;
        }

        public void GenericMethod<X>(X x)
        {
            Console.WriteLine(x.ToString());
        }
    }

    delegate T NumberChanger<T>(T n);
}
